# -*- coding: utf-8 -*-
"""
Created on Mon Nov 18 13:00:38 2013

@author: wudong

File location :
D:/MyCodeLib/MyAbaqusLib/

usage :
import numpy as np
import abaHelper as ah

Reload the updated module :
import abaHelper as ah
reload(ah)

"""
import numpy as np
import os

# short for textRepr.prettyPrint
def pp(obj):
	from textRepr import prettyPrint
	prettyPrint(obj)
	pass

# read data from text data file
def loadtxt(fname, delimiter=',', comments='#', converters=None,
			skiprows=0, usecols=None, unpack=False):
	X = np.loadtxt(fname, np.dtype(np.float), comments, delimiter,
		converters, skiprows, usecols, unpack)
	return X

# save numpy array X to text file
def savetxt(fname, X, fmt='%.6e', delimiter=', '):
	np.savetxt(fname, X, fmt=fmt, delimiter=delimiter)
	pass

# convert a 2D numpy array to abaqus table
#   abaqus table:
#       ((1,2), (3,4), (5,6))
def arrayToTable(arrayData):
	table = []
	(row,col) = arrayData.shape
	for i in range(row):
		rowData = []
		for j in range(col):
			rowData.append(arrayData[i,j])
			pass
		table.append(tuple(rowData))
	return tuple(table)
	
def tableToArray(table):
	row = len(table)
	col = len(table[0])
	arrayData = np.zeros(shape=(row,col))
	for i in range(row):
		for j in range(col):
			arrayData[i,j] = table[i][j]
	return arrayData

def loadArray(fname, delimiter=','):
	arrayData = np.loadtxt(fname, delimiter=delimiter)
	return arrayData

def loadTable(fname, delimiter=','):
	arrayData = loadArray(fname, delimiter=delimiter)
	table = arrayToTable(arrayData)
	return table

def saveArray(fname, X, fmt='%13.6e', delimiter=','):
	np.savetxt(fname, X, fmt=fmt, delimiter=delimiter)

#
def isSamePath(path1, path2):
	return os.path.normpath(path1)==os.path.normpath(path2)

def openOdb(odbPath):
	from abaqus import session
	import odbAccess
	myOdb = None
	absOdbPath = os.path.abspath(odbPath)
	for path in session.odbs.keys():
		if isSamePath(absOdbPath,path):
			myOdb = session.odbs[path]
	if myOdb==None:
		myOdb = odbAccess.openOdb(path=absOdbPath)
	return myOdb

def getOdbNodeSets(odb):
	instance = odb.rootAssembly.instances.values()[0]
	return instance.nodeSets
	
def getOdbElemSets(odb):
	instance = odb.rootAssembly.instances.values()[0]
	return instance.elementSets

def getOdbNodeLabel(odb,nodeSetName):
	instance = odb.rootAssembly.instances.values()[0]
	nodeLabel = instance.nodeSets[nodeSetName].nodes[0].label
	return nodeLabel

def getOdbNodeHistData(odb,stepName,nodeSetName,varName):
	instance = odb.rootAssembly.instances.values()[0]
	nodeLabel = instance.nodeSets[nodeSetName].nodes[0].label
	histName = 'Node %s.%d' % (instance.name,nodeLabel)
	step = odb.steps[stepName]
	histRegion = step.historyRegions[histName]
	histData = histRegion.historyOutputs[varName].data
	histData = tableToArray(histData)
	return histData

def getModelNodeLabel(model,nodeSetName):
	instance = model.rootAssembly.instances.values()[0]
	nodeLabel = instance.sets[nodeSetName].nodes[0].label
	return nodeLabel

def getModelBlockPosition(model, blockPrefix):
	if blockPrefix == '':
		return len(model.keywordBlock.sieBlocks)-1
	pos = 0
	for block in model.keywordBlock.sieBlocks:
		if block[0:len(blockPrefix)].lower()==blockPrefix.lower():
			return pos
		pos=pos+1
	return -1

def setSpringDashpot(model,portionName,nodeLabel,dof,
		spBehavior,spCoef, dpBehavior,dpCoef):
	import regionToolset
	instance = model.rootAssembly.instances.values()[0]
	modelNodes = instance.nodes
	nodeRegion = modelNodes.sequenceFromLabels((nodeLabel,))
	region=regionToolset.Region(nodes=nodeRegion)
	sprDashpotName = 'sd_%s_%d_%d' % (portionName,nodeLabel,dof)
	model.rootAssembly.engineeringFeatures.SpringDashpotToGround(
		name=sprDashpotName, region=region, orientation=None, dof=dof, 
		springBehavior=spBehavior, springStiffness=spCoef, 
		dashpotBehavior=dpBehavior, dashpotCoefficient=dpCoef )

def applyConcentratedForce(model,stepName,portionName,nodeLabel,
		dof,ampData,amp=1.0):
	from abaqusConstants import STEP,SOLVER_DEFAULT,UNIFORM
	import regionToolset
	instance = model.rootAssembly.instances.values()[0]
	modelNodes = instance.nodes
	nodeRegion = modelNodes.sequenceFromLabels((nodeLabel,))
	region=regionToolset.Region(nodes=nodeRegion)
	#
	ampName = 'Amp_%s_%d_%d' % (portionName,nodeLabel,dof)
	ampDataTable = arrayToTable(ampData)
	model.TabularAmplitude(name=ampName, timeSpan=STEP, 
		smooth=SOLVER_DEFAULT, data=ampDataTable)
	#
	loadName = 'CF_%s_%d_%d' % (portionName,nodeLabel,dof)
	cfs = [0,0,0]
	cfs[dof-1] = amp
	model.ConcentratedForce(name=loadName, createStepName=stepName,
		region=region, cf1=cfs[0], cf2=cfs[1], cf3=cfs[2], amplitude=ampName, 
		distributionType=UNIFORM, field='', localCsys=None)

